package cluster

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"quickK8s/config"
	"quickK8s/pkg/utils"
)

type Manager struct {
	cfg      *config.ClusterConfig
	executor utils.CommandExecutor
	env      map[string]string
}

func NewManager(cfg *config.ClusterConfig, executor utils.CommandExecutor) *Manager {
	return &Manager{
		cfg:      cfg,
		executor: executor,
		env:      cfg.Cluster.Env,
	}
}

// InstallRequiredPackages 安装必要的软件包
func (m *Manager) InstallRequiredPackages() error {
	// 获取当前工作目录
	workDir, err := os.Getwd()
	if err != nil {
		return fmt.Errorf("获取当前目录失败: %v", err)
	}

	// 检查 packages 目录是否存在
	packagesDir := filepath.Join(workDir, "packages")
	if _, err := os.Stat(packagesDir); os.IsNotExist(err) {
		return fmt.Errorf("packages 目录不存在，请先创建目录并放入所需的软件包")
	}

	// 准备离线软件包目录
	if err := m.executor.RunCommand("mkdir", "-p", "/tmp/packages"); err != nil {
		return fmt.Errorf("创建临时目录失败: %v", err)
	}

	// 使用绝对路径复制离线包到临时目录
	if err := m.executor.RunCommand("sudo", "cp", "-rf", packagesDir, "/tmp/"); err != nil {
		// 如果 sudo cp 失败，尝试先修改目录权限
		_ = m.executor.RunCommand("sudo", "chmod", "777", "/tmp")
		if err := m.executor.RunCommand("sudo", "cp", "-rf", packagesDir, "/tmp/"); err != nil {
			return fmt.Errorf("复制离线包失败: %v", err)
		}
	}

	// 在所有节点上创建目录并复制软件包
	if err := m.executeOnAllNodes("mkdir -p /tmp/packages"); err != nil {
		return fmt.Errorf("在节点上创建目录失败: %v", err)
	}

	// 复制软件包到所有节点
	allNodes := append(m.cfg.Cluster.Masters, m.cfg.Cluster.Nodes...)
	// 获取本机IP
	localIP, err := utils.GetLocalIP()
	if err != nil {
		log.Printf("警告: 获取本机IP失败: %v", err)
	}
	fmt.Println("")

	for _, node := range allNodes {
		// 跳过本机
		if localIP != "" && node == localIP {
			continue
		}

		// 获取所有包文件
		files, err := filepath.Glob("/tmp/packages/*")
		if err != nil {
			return fmt.Errorf("查找包文件失败: %v", err)
		}

		// 逐个文件复制
		for _, file := range files {
			if err := m.executor.RunCommand("scp", "-r", "-o", "StrictHostKeyChecking=no",
				file,
				fmt.Sprintf("root@%s:/tmp/packages/", node)); err != nil {
				return fmt.Errorf("复制文件 %s 到节点 %s 失败: %v", file, node, err)
			}
		}
	}

	// 安装软件包的命令
	commands := []string{
		// Debian/Ubuntu
		"cd /tmp/packages && dpkg -i *.deb || true",
		"apt-get -f install -y",
		// CentOS/RHEL
		// "cd /tmp/packages && rpm -ivh --force --nodeps *.rpm || true",
		// "yum install -y iptables ebtables socat || true",
	}

	// 在所有节点上执行安装命令
	for _, cmd := range commands {
		if err := m.executeOnAllNodes(cmd); err != nil {
			log.Printf("警告: 执行命令失败: %v", err)
		}
	}

	// 清理临时文件
	_ = m.executeOnAllNodes("rm -rf /tmp/packages")
	_ = m.executor.RunCommand("rm", "-rf", "/tmp/packages")

	log.Println("必要软件包安装完成")
	return nil
}

// executeOnAllNodes 在所有节点上执行命令
func (m *Manager) executeOnAllNodes(command string) error {
	allNodes := append(m.cfg.Cluster.Masters, m.cfg.Cluster.Nodes...)

	// 在每个节点上执行命令
	for _, node := range allNodes {
		if err := m.executor.RunCommand("sshpass", "-p", m.cfg.Cluster.Password,
			"ssh", "-o", "StrictHostKeyChecking=no",
			fmt.Sprintf("root@%s", node), command); err != nil {
			return fmt.Errorf("在节点 %s 执行命令失败: %v", node, err)
		}
	}
	return nil
}
